android ViewPager 仿画廊/图书翻页 与 palette 使用 您所在的位置:网站首页 android viewpager 切换 android ViewPager 仿画廊/图书翻页 与 palette 使用

android ViewPager 仿画廊/图书翻页 与 palette 使用

2023-02-13 15:10| 来源: 网络整理| 查看: 265

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

废话不多说,先来看看完成的效果!

总结实现效果:

ViewPager 实现无限自动播放 ViewPager 实现中间大,两边小 [仿画廊效果] ViewPager 实现图片叠加[仿图书翻页效果] palette 调色板实现识别图片颜色,随着图片的变化来改变背景色的变化 普通ViewPager实现

先不管三七二十一,先吧最基本的ViewPager实现,之后在在基本的ViewPager上修改!

不用复制代码,先看思路就行,底部会给出完整代码!

activity_palette.xml布局: 在这里插入图片描述 java代码:

//设置适配器 viewPager.setAdapter(new BannerAdapter(this, mDrawables)); //Pager之间的间距 viewPager.setPageMargin(20); //预加载 viewPager.setOffscreenPageLimit(3); //默认第一张图 左右都有图 viewPager.setCurrentItem(1); 复制代码

BannerAdapter 适配器:

public class BannerAdapter extends PagerAdapter { private int[] mData; private Context mContext; public BannerAdapter(Context ctx, int[] data) { this.mContext = ctx; this.mData = data; } @Override public int getCount() { return mData.length;// 返回数据的个数 } @Override public Object instantiateItem(final ViewGroup container, final int position) {//子View显示 View view = View.inflate(container.getContext(), R.layout.banner_item_layout, null); ImageView imageView = view.findViewById(R.id.iv_icon); imageView.setImageResource(mData[position]); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(mContext, "当前条目:" + position, Toast.LENGTH_SHORT).show(); } }); container.addView(view);//添加到父控件 return view; } @Override public boolean isViewFromObject(View view, Object object) { return view == object;// 过滤和缓存的作用 } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object);//从viewpager中移除掉 } } 复制代码

先来看看目前的效果:

就是一个很简单的ViewPager没什么好说的!

思路分析:

要想完成画廊的效果,那么必须吧viewPager分为以下几步骤:

让ViewPager显示出左右两侧的View 无限滑动 自定义ViewPager 滑动动画,滑动过程中中间大,两边小 自动播放

那就来根据思路实现效果吧 :

让ViewPager显示出左右两侧的View

在这里插入图片描述 来看看效果:

无限滑动

在这里插入图片描述

这个也是真 的简单,直接取%即可实现

来看看效果:

中间大,两边小效果 要想实现这个效果,就要来介绍本篇重中之重! ViewPager.PageTransformer

ViewPager.PageTransformer

先来看使用:

viewPager.setPageTransformer(true, new ScaleTransformer()); 复制代码 参数一: 是否逆转,我没看出有什么效果,懂这个参数的记得在评论区留言哦! 参数二: 用来控制ViewPager 动画的 public class ScaleTransformer implements ViewPager.PageTransformer { private static final float MAX_SCALE = 1.0f;//0缩放 private static final float MIN_SCALE = 0.80f;//0.85缩放 @Override public void transformPage(@NonNull View view, float position) { } } 复制代码

实现implements ViewPager.PageTransformer重写transformPage()方法,有2个参数

/** * A PageTransformer is invoked whenever a visible/attached page is scrolled. * This offers an opportunity for the application to apply a custom transformation * to the page views using animation properties. * *

As property animation is only supported as of Android 3.0 and forward, * setting a PageTransformer on a ViewPager on earlier platform versions will * be ignored.

*/ public interface PageTransformer { /** * Apply a property transformation to the given page. * * @param page Apply the transformation to this page * @param position Position of page relative to the current front-and-center * position of the pager. 0 is front and center. 1 is one full * page position to the right, and -1 is one page position to the left. */ void transformPage(@NonNull View page, float position); } 复制代码

这个方法在onPageScrolled页面滑动的过程中回调

@CallSuper protected void onPageScrolled(int position, float offset, int offsetPixels) { ....省略....... if (mPageTransformer != null) { ....省略....... mPageTransformer.transformPage(child, transformPos); } } mCalledSuper = true; } 复制代码

transformPage参数:

参数一: 当前view 参数二:当前view的位置

这里比较抽象,画张图看看

image.png

红色当前View 蓝色 左侧View 黄色 右侧View

不滑动状态position变化:

红色蓝色黄色position = -1position = 0position = 1

滑动状态position变化:

状态红色蓝色黄色左滑动position < -10 < position < -11 < position < 0右滑动-1 < position < 00 < position < 1position > 1

先来打印一下看看position的值: 在这里插入图片描述 还看不懂? 再来画一张图:

在这里插入图片描述

好了,position就介绍到这里!

先简简单单修改代码,先看看效果:

public class ScaleTransformer implements ViewPager.PageTransformer { private static final float MAX_SCALE = 1.0f;//0缩放 private static final float MIN_SCALE = 0.80f;//0.85缩放 @Override public void transformPage(@NonNull View view, float position) { //position != 0 表示左侧和右侧的view if (position != 0) { view.setScaleX(MIN_SCALE); view.setScaleY(MIN_SCALE); } else { view.setScaleX(MAX_SCALE); view.setScaleY(MAX_SCALE); } } } 复制代码

效果:

可以看到,要实现的效果已经渐渐接近了!

在加上滑动时候放大缩小即可

public class ScaleTransformer implements ViewPager.PageTransformer { private static final float MAX_SCALE = 1.0f;//0缩放 private static final float MIN_SCALE = 0.80f;//0.85缩放 @Override public void transformPage(@NonNull View view, float position) { if (position < 1) { float scaleFactor = MIN_SCALE + (1 - Math.abs(position)) * (MAX_SCALE - MIN_SCALE); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { view.setScaleX(MIN_SCALE); view.setScaleY(MIN_SCALE); } } } 复制代码

这里涉及到一个小算法

float scaleFactor = MIN_SCALE + (1 - Math.abs(position)) * (MAX_SCALE - MIN_SCALE); 复制代码

指的就是变化过程中view的大小

这段代码要细细的品味一下!!!很关键!!

来看看湿滑的效果:

无限自己滚动

这段代码也是简单的很:

直接上代码不多贝贝:

//用来记录是否按压,如果按压,则不滚动 boolean isDown ; Timer timer = new Timer(); //定时器播放ViewPager TimerTask timerTask = new TimerTask() { @Override public void run() { if (!isDown) { //获取到当前的位置 int page = viewPager.getCurrentItem() + 1; runOnUiThread(() -> viewPager.setCurrentItem(page)); } } }; // 每2.5秒执行一次 timer.schedule(timerTask, 0, 2500); viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //viewPager滑动的时候,设置不让滚动 isDown = true; } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { //ViewPager不点击了让滚动 isDown = false; } }); 复制代码

这段代码过于简单,就不看效果了!

仿图书效果

这个效果和仿画廊流程一样,也是对PageTransformer的操作,直接上代码了!

public class StackPageTransformer implements ViewPager.PageTransformer { private final ViewPager viewPager; private final float SCALE_VALUE = 1f; //View 之间的偏移量 private final float DEVIATION = 60f; //旋转 private final float ROTATION = 60f; //图片是否叠加【默认不叠加】 private final boolean isStack = false; public StackPageTransformer(ViewPager viewPager) { this.viewPager = viewPager; } @Override public void transformPage(@NonNull View view, float position) { Log.i("szjPosition2", position + ""); /* * 当不滑动状态下: * position = -1 左侧View * position = 0 当前View * position = 1 右侧View * * 当滑动状态下: * 向左滑动: [ position < 0 && position > -1] * 左侧View position < -1 * 当前View 0 ~ -1 * 右侧View 1 ~ 0 * * 向右滑动:[position > 0 && position < 1 ] * 左侧View -1 < position < 0 * 当前View 0 ~ 1 * 右侧View position > 1 */ int pageWidth = viewPager.getWidth(); //隐藏左侧侧的view if (position == -1) { view.setVisibility(View.GONE); } else { view.setVisibility(View.VISIBLE); } //当前View和右侧的View [让右侧View和当前View叠加起来] if (position >= 0) { float translationX; //这里不要晕! 改变isStack来看看效果吧!! if (isStack) { translationX = DEVIATION - (pageWidth) * position; } else { translationX = (DEVIATION - pageWidth) * position; } Log.i("szjTranslationX", translationX + ""); view.setTranslationX(translationX); } //当前view if (position == 0) { view.setScaleX(SCALE_VALUE); view.setScaleY(SCALE_VALUE); } else { //左侧已经隐藏了,所以这里值的是右侧View的偏移量 float scaleFactor = Math.min(SCALE_VALUE - position * 0.1f, SCALE_VALUE); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } //向左滑动 if (position < 0 && position > -1) { //旋转 view.setRotation(ROTATION * position); view.setAlpha(1 - Math.abs(position)); } else { //透明度 其他状态不设置透明度 view.setAlpha(1); } //向右滑动 if (position > 0 && position < 1) { view.setRotation(0); } } } 复制代码

看看效果:

palette 调色板

先添加依赖:

implementation 'com.android.support:palette-v7:26.0.0-alpha1' 复制代码

简单介绍: palette 传入一张Bitmap,然后他会通过图片像素点来分析出颜色占比,提取出你需要的颜色!!

使用:

public void initPalette(Bitmap bitmap) { new Thread(() -> Palette.from(bitmap).generate(palette -> { //以RGB压缩整数的形式从调色板返回静音和深色。 int darkMutedColor = palette.getDarkMutedColor(Color.TRANSPARENT); //暗 柔和 [以RGB压缩整数的形式从调色板返回静音和浅色。] int lightMutedColor = palette.getLightMutedColor(Color.TRANSPARENT); //暗 鲜艳 [以RGB压缩整数的形式从调色板返回深色和鲜艳的颜色。] int darkVibrantColor = palette.getDarkVibrantColor(Color.TRANSPARENT); //量 鲜艳 [以RGB压缩整数的形式从调色板返回明亮的颜色。] int lightVibrantColor = palette.getLightVibrantColor(Color.TRANSPARENT); //柔和 [将调色板中的静音颜色作为RGB压缩整数返回。] int mutedColor = palette.getMutedColor(Color.TRANSPARENT); //以RGB压缩整数形式返回调色板中最鲜艳的颜色。 int vibrantColor = palette.getVibrantColor(Color.TRANSPARENT); //从调色板中返回一个明亮且充满活力的样例。可能为空。 Palette.Swatch lightVibrantSwatch = palette.getLightVibrantSwatch(); int hotColor = Color.TRANSPARENT; if (lightVibrantSwatch != null) { //谷歌推荐的:图片的整体的颜色rgb的混合痔---主色调 int rgb = lightVibrantSwatch.getRgb(); hotColor = getTranslucentColor(0.7f, rgb); } // 拿到颜色 这里就可以给View 设置颜色了 })).start(); } 复制代码

然后通过随机图片,设置不同的图片来测试一下管用不管用!

来看看效果:

这里用到了动态代码设置渐变,代码很简单,给大家看看吧

/** * TODO 设置渐变颜色 * * @param view 需要设置的View * @param colors 渐变颜色 * @param type 渐变位置 例如:GradientDrawable.Orientation.LEFT_RIGHT 从左到右 * @param radius 圆角 */ public void setGradualChange(View view, int[] colors, GradientDrawable.Orientation type, int radius) { GradientDrawable drawable = new GradientDrawable(type, colors); drawable.setCornerRadius(radius); view.setBackground(drawable); } 复制代码

完整项目

原创不易,您的点赞就是对我最大的支持!!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有